import os.path
from io import BytesIO
import mimetypes
import requests
import paramiko

from requests import Response
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from yat.test import macro
from yat.test import Node


class BaseOpsApi:
    def __init__(self, token):
        self.headers = None
        self.log = Logger()
        self.comm_sh = CommonSH()
        self.token = token
        self.ip = f"https://{macro.DATAKIT_HOST}:{macro.DATAKIT_PORT}"

    def get_plugins_base_ops_clusterTask_host_list(self, system_os: str = '',
                                                   os_version: str = '', cpu_arch: str = '') -> Response:
        """
        获取已导入服务器的列表
        :param system_os: 操作系统
        :param os_version: 操作系统版本
        :param cpu_arch: cpu架构
        :return: 符合条件的已导入的服务器的列表
        """
        api = f'/plugins/base-ops/clusterTask/host/list?os={system_os}&osVersion={os_version}&cpuArch={cpu_arch}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_cluster_Task_host_user(self, host_id: str) -> Response:
        """
        并行安装获取指定服务器的用户
        :param host_id: 服务器hostId
        :return: 获取用户列表
        """
        api = f'/plugins/base-ops/clusterTask/hostUser/{host_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_clusterTask_host(self, ip: str) -> Response:
        """
        获取服务器操作系统信息
        :param ip: 服务器ip
        :return: 服务器信息
        """
        api = f'/plugins/base-ops/clusterTask/host/{ip}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_install_Package_Manager_hasName(self, server_name) -> Response:
        """
        判断安装包包名是否重复
        :param server_name: 下载的安装包名称
        :return:
        """
        api = f'/plugins/base-ops/installPackageManager/hasName?name={server_name}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_install_Package_Manager_v2_list_package(self, package_data: dict) -> Response:
        """
        查询安装包是否存在
        :param package_data: 安装包信息
        :return:
        """
        api = f"/plugins/base-ops/installPackageManager/v2/list/package"
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False, json=package_data)
        return response

    def get_plugins_base_ops_cluster_task_node_create(self, batch_cluster_conf: dict) -> Response:
        """
        集群配置
        :param batch_cluster_conf: 集群配置信息
        :return:
        """
        api = f"/plugins/base-ops/cluster/task/node/create"
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False, json=batch_cluster_conf)
        return response

    def get_plugins_base_ops_cluster_Task_create(self, batch_node_conf: dict) -> Response:
        """
        节点配置
        :param batch_node_conf: 节点配置信息
        :return:
        """
        api = f"/plugins/base-ops/clusterTask/create"
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False, json=batch_node_conf)
        return response

    def get_plugins_base_ops_opsCluster_listInstallPackage(self, package_version: str) -> Response:
        """
        获取已上传或已下载的安装包列表
        :param package_version:（极简版：MINIMAL_LIST，）
        :return:
        """
        api = f'/plugins/base-ops/opsCluster/listInstallPackage?version={package_version}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_installPackageManager_list(self, package_version: str) -> Response:
        """
        获取可在线下载安装包列表
        :param package_version:（极简版：MINIMAL_LIST，）
        :return:
        """
        api = f'/plugins/base-ops/installPackageManager/list?packageVersion={package_version}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_installPackageManager_hasName(self, pkg_name: str) -> Response:
        """
        校验安装包名称是否存在
        :param pkg_name: 待校验安装包名称
        :return:
        """
        api = f'/plugins/base-ops/installPackageManager/hasName?name={pkg_name}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_plugins_base_ops_installPackageManager(self, data: dict, file_path: str, node_name: str) -> Response:
        """
        上传数据库安装包
        :param node_name: 待上传文件保存的节点
        :param data: 安装包版本信息
        :param file_path: 待上传安装包路径
        :return:
        """
        node = Node(f'{node_name}')
        file_name = os.path.basename(file_path)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(node.ssh_host, username=node.ssh_user, password=node.ssh_password)
        sftp = ssh.open_sftp()

        api = "/system/plugins/offline_install"
        self.headers = {
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        file_buffer = BytesIO()
        with sftp.file(file_path, 'rb') as remote_file:
            file_buffer.write(remote_file.read())
        file_buffer.seek(0)
        mime_type, _ = mimetypes.guess_type(file_name)
        if mime_type is None:
            if file_name.endswith('.gz'):
                mime_type = 'application/gzip'
            elif file_name.endswith('.bz2'):
                mime_type = 'application/x-bzip2'
            else:
                mime_type = 'application/octet-stream'
        files = {'file': (file_name, file_buffer, mime_type)}
        response = requests.post(url=url, files=files, json=data, headers=self.headers, verify=False)
        ssh.close()
        return response

    def get_plugins_base_ops_installPackageManager_getCpuArch(self, install_package_path: str,
                                                              version: str) -> Response:
        """
        获取安装包的架构
        :param install_package_path:安装包上传路径
        :param version: 安装包版本（极简版：MINIMAL_LIST，）
        :return:
        """
        api = f'/plugins/base-ops/installPackageManager/getCpuArch?installPackagePath={install_package_path}&version={version}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_opsCluster_listCluster(self):
        """
        查看集群列表
        :return:
        """
        api = '/plugins/base-ops/opsCluster/listCluster'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_plugins_base_ops_opsCluster_uninstall(self, data: dict) -> Response:
        """
        卸载集群
        :param data: 集群信息
        :return:
        """
        api = '/plugins/base-ops/opsCluster/uninstall'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def post_plugins_base_ops_opsCluster_download(self, data: dict) -> Response:
        """
        在线下载安装包
        :param data:{
                    "businessId": 事务id ,
                    "connectType": "DOWNLOAD_INSTALL_PACKAGE" ,
                    "fileName": 安装包名称 ,
                    "resourceUrl": 下载地址 ,
                    "targetPath": 下载路径 ,
                    }
        :return:
        """
        api = '/plugins/base-ops/opsCluster/download'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_opsCluster_env(self, host_id: str, expected_os: str) -> Response:
        """
        安装部署前环境监测
        :param host_id: 服务器id
        :param expected_os: os类型
        :return:
        """
        api = f'/plugins/base-ops/opsCluster/env/{host_id}?expectedOs={expected_os}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_opsCluster_hasName(self, cluster_name: str) -> Response:
        """
        检查集群名称是否已存在
        :param cluster_name: 集群名称
        :return:
        """
        api = f'/plugins/base-ops/opsCluster/hasName?name={cluster_name}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_host_portUsed(self, host_id: str, port: int) -> Response:
        """
        查询端口是否已被占用
        :param host_id: 服务器id
        :param port: 端口号
        :return:
        """
        api = f'/plugins/base-ops/host/portUsed/{host_id}?port={port}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_plugins_base_ops_opsCluster_install(self, data: dict) -> Response:
        """
        安装数据库
        :param data: 数据库信息
        :return:
        """
        api = '/plugins/base-ops/opsCluster/install'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_plugins_base_ops_host_pathEmpty(self, host_id: str, install_path: str) -> Response:
        """
        查询路径是否为空
        :param host_id:
        :param install_path:
        :return:
        """
        api = f'/plugins/base-ops/host/pathEmpty/{host_id}?path={install_path}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_plugins_base_ops_opsCluster_quickInstall(self, data:dict) -> Response:
        """
        一键安装数据库
        :param data:
        :return:
        """
        api = '/plugins/base-ops/opsCluster/quickInstall'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response